Краткий ответ: «Почему я должен включать каталог заголовочных файлов X в E?» ... Вы не должны. Клиенту Y не нужно знать, что Y зависит от X.
Длинный ответ: Вы должны включать заголовок X в E, только если интерфейс (подписи) Y использует вещи, объявленные в заголовке X. Но если заголовок Y был " правильно построенный ", тогда они будут включать заголовки X в сам заголовок Y, и вам не нужно будет явно включать заголовок X в E (включая заголовок Y будет автоматически включать заголовок X).
Под «правильно построенным» я подразумевал, что если подписи в Y1.h в Y зависят, скажем, от X3.h и X7.h, то Y1.h должен включать эти файлы (прямо или косвенно). Таким образом, любой клиент Y1.h не должен знать, что это за зависимости, и должен будет включать эти зависимости отдельно в результате. В качестве простого теста, .cpp, состоящий из следующей строки, должен компилироваться без проблем:
#include "Y1.h"
Хорошей практикой является включение "Y1.h" перед включением любого другого файла в Y1.cpp. Если в Y1.h отсутствуют зависимости, компилятор сообщит вам.