$watch only looks at the object references (it compares them using ===), so since $scope.bits is always the same array instance, even though its contents have changed, it doesn't fire your listener.
You can pass an additional parameter to $watch that makes it do comparison of the contents of the objects:
$scope.$watch('bits', function() {}, true);
I'd never heard of using bits.length
as @robertklep suggested, but that also looks elegant and I'd upvote it if he posted it as an answer.