when you have copy-pasted code (private functions) between different classes.
you would need to split your algorithm into different steps, implemented in the abstract class when in common between the different implementations. On the other hand, the steps which are different will be implemented in the concrete classes.
when your classes have related behavior
Advantages
avoid duplicated code ({{Clean Code}})
separate algorithms into private methods, simpler and easier to test (unit test)
better concrete implementation of algorithms, removing common parts of a problemn into a abstract class