From ng-book:
When Angular starts to run and generate the view, it will create a binding from the root ng-app
  element to the $rootScope. This $rootScope is the eventual parent of all $scope objects.
  The $rootScope object is the closest object we have to the global context in an
  Angular app. It’s a bad idea to attach too much logic to this global context, in the
  same way that it’s not a good idea to dirty the JavaScript global scope.
You are right, you should definitely use Services to share data and logic between your modules.
Putting a lot of logic in your $rootScope means having bad maintainability and modularity in your application, it is also very difficult to test issues.
I highly suggest you to take a look at:
I know it may be easy to attach everything to $rootScope, but It is just difficult to work on it, make little changes, reusing your code for other applications or modules and test your application in general.
EDIT
Recently I had to fetch some items from API and catch these items in order to show them in a certain view. The item fetching mechanism was in a certain Factory, while the mechanism to format and show the items was in a Controller.
So, I had to emit an event in the Factory when items got fetched and catch this event in the Controller.
$rootScope way
//Factory
$rootScope.$broadcast('refreshItems', items);
//Controller
$scope.$on('refreshItems', doSomething());
It clearly worked but I didn't really like to use $rootScope and I've also noticed that the performance of that task were pretty miserable.
Then I tried giving a shot to Postal.js:
Postal.js is an in-memory message bus - very loosely inspired by AMQP - 
  written in JavaScript. Postal.js runs in the browser, or on the server
  using node.js. It takes the familiar "eventing-style" paradigm (of
  which most JavaScript developers are familiar) and extends it by
  providing "broker" and subscriber implementations which are more
  sophisticated than what you typically find in simple event
  emitting/aggregation.
I tried using Postal.js for this kind of needs and I found out that it is really faster than using $rootScope for this purpose.
//Factory
$scope.$bus.publish({
                  channel : 'reloadItems',
                  topic   : 'reloadItems'
                  data    : items
);
//Controller
$scope.$bus.subscribe({
  channel  : 'reloadItems',
  topic    : 'reloadItems',
  callback : function () {
    resetAndLoadItems();
  }
});
I hope I've been helpful.