I ran into this problem myself, and I solved it with something similar to @ValentynShybanov's comment but not quite the same. my solution does not require you to prefix all properties as you stated in the comment.
see a working plunkr
var entireScope = {};
for ( var i in $scope ){
if ( i[0] !== '$' && i !== 'this' && i !== 'constructor'){
console.log(i);
entireScope[i] = $scope[i];
}
}
$scope.entireScope = entireScope;
$scope.$watch('entireScope', function( newValue, oldValue ){
$log.info('entireScope has changed',newValue, oldValue);
}, true);
as you see the solution is quite the same, but in fact it adds another property to the scope rather than replacing the structure you already have. this new property represents the entire scope (hence its name) and you can watch it.
the loop I wrote might be too generic, you can replace it with a customized initialization. for example:
$scope.entireScope = { 'someVal' : $scope.someVal }
this solution answers your needs and spares you the need to refactor the code.