hook_module_implements_alter() to put hook implementations into separate files - bad practice?
I just found the piece of information that was missing.
EDIT: And another one.

Problem with module_invoke()

module_invoke_all() always calls module_implements(), which checks the module include file by checking both hook_hook_info() and hook_module_implements_alter().

However, module_invoke() only checks hook_hook_info() and not hook_module_implements_alter().

module_invoke() is called e.g. in _block_render_blocks() for hook_block_view().
This means that hook_module_implements_alter() is not a good solution to split a hook_block_view() implementation into a separate file.

This has been a problem in Crumbs, see https://www.drupal.org/node/2328535.

For other hooks it generally works ok, but you never know if a specific module wants to use module_invoke() instead of module_invoke_all().

module_implements() cache polluted in bootstrap.

Another problem is caused by a core issue reported here:
module_implements_cache() can be polluted by hook_boot() implementations calling module_invoke_all() directly or indirectly

This applies only to non-boot modules, where it can happen that the implementation of hook_module_implements_alter() is never discovered.


An unexpected chain of events causes module_implements($hook) being called from hook_boot().
The $hook can be any random hook, it does not need to be related to the module we are working on.
This causes module_implements('module_implements_alter') to be called.
Drupal looks for all implementations of hook_module_implements_alter().
At this time, MODULENAME.module is not included yet.
Therefore, for the rest of the request, Drupal assumes that the implementation MODULENAME_module_implements_alter() does not exist.
Later in the request, implementations of other hooks are being discovered, but the implementations by MODULENAME are not being found, because MODULENAME_module_implements_alter() is not being executed.


Alternatives

require_once

Alternatives have already been mentioned. Instead of these tricks, one can include the file directly. There may be a tiny performance impact but this is probably overshadowed by a lot of other things in Drupal.

But, instead of using module_load_include(), I would suggest a more direct solution:

require_once __DIR__ . '/crumbs.block.inc';


Or to be PHP 5.2 compatible:

require_once dirname(__FILE__) . '/crumbs.block.inc';


Why not module_load_include()?

There is generally no need to call module_load_include(), it could even be detrimental, if the *.module file is included from you-dont-know-where (e.g. from settings.php), and you don't know if module_load_include() is available.

This function is mostly there to help you determine the location of other modules. But if you are including within the same module, it is generally safer and easier and faster to work with relative file paths and explicit require_once.

Call to helper function

As mentioned by Jimajamma, you can also implement the hook in the main *.module file, and then include another file and call a helper function from there. This is done e.g. in Display suite.

This solution is ok, although I think it still clutters the main file, and gives you even more places to look.

And here likewise you can use require_once instead of module_load_include(), if it is within the same module.