In my articles I wrote about a possible solution to your problem. In my vision of ECS, I group the systems according their context and level of abstraction. When I talk about context, I mean the scope of the systems. For example, are the systems handling enemies? Are the systems handling weapons? Are the systems handling the player? Once I give a context to the systems, I group them under the same namespace, like PlayerSystems, EnemySystems and so on.
Level of abstraction is instead about how abstracted a system is, for example: is it the system that manages the general physic collision? Or is it the system that manages the collision between enemies and enemy targets? The latter is less abstracted than the first one.
In this scenario, what I would do is to let the general system, that manages collisions, communicate with the less abstracted systems.
The communication could happen through an observer, defined in the same namespace of the abstracted system and used by injection by the other systems.
Alternatively (and that's what I actually do), I let the systems communicate through the components. The EnemyTargetColliderSystem knows exactly the same component used by the PhysicCollisionSystem therefore knows when an enemy collides with something. At that point it must check if something is a valid target.
This is just one way to solve the problem, it really depends if you want to take advantage of the computation already performed by the PhysicCollisionSystem. If not, you can simply perform a collision check between all the enemies and possible enemy targets inside the EnemyCollisionSystem.
Be careful that I call it enemy target and not player. It would be wrong to let an EnemyEngine know about a component relative to the PlayerEngine.
if you want to know more about my point of view on ECS, you can read my articles starting from this one: http://www.sebaslab.com/the-truth-behind-inversion-of-control-part-i-dependency-injection/