Я использовал как частное, так и защищенное наследование в тот или иной момент.
Частное наследование полезно, когда вы хотите, чтобы что-то имело поведение базового класса, а затем иметь возможность переопределить эту функциональность, но вы не хотите, чтобы весь мир знал об этом и использовал его. Вы по-прежнему можете использовать интерфейс частного класса, если функция возвращает этот интерфейс. Это также полезно, когда вы можете зарегистрировать вещи для прослушивания обратных вызовов, поскольку они могут регистрировать себя с помощью частного интерфейса.
Защищенное наследование особенно полезно, когда у вас есть базовый класс, который извлекает полезную функциональность из другого класса, но вы хотите, чтобы только его производные классы могли использовать его.