ヘッダーファイルの循環参照

もう昔から散々言われている話題だと思いますが、ヘッダーファイルの循環参照に手を焼いています。相互に定義を参照するケースが増えた結果、前方宣言を忘れたために引き起こるコンパイルエラーが多発するようになり、ウザくてたまりません。エラーを解消するために、その都度、前方宣言を追加するのですが、ヘッダーファイルがだんだんと複雑になってくるのも気持ちが悪いです。
ちなみに、下の図は今開発しているレイトレーサーのヘッダーファイルからインクルードしているファイル名を正規表現で抜き出して、その参照関係をグラフ化したもの。最近は幾何データを扱うクラスが煩雑になってきたので、ここをどうにかしたいと考えています。

単純に解決するならば、循環参照しているヘッダーファイルを一つのファイルにまとめたらいいかもしれません。しかし、そうするとプログラムの全体構造が俯瞰しにくくなるので嫌ですね。やはりメンテナンスのしやすさを考慮すると、ファイル名を見ただけでどのようなモデルでプログラムが構成されているのか、ざっと理解できるようにしておきたい所です。
私の件のように、C/C++で中規模以上のソフトウェアを開発する場合、循環参照の問題は避けては通れないと思うのですが、他所では一般にどのような解決策をとっているのか気になります。何か定石であるバッドノウハウ的な手法が存在するのでしょうか?それとも、循環参照が解消されるよう設計を工夫するしかないのでしょうか?