Oi pessoal, tive esse problema há tempos atrás, ralei a beça mais consegui resolver.
tem como vcs fazerem assim:
<rich:dataTable value="#{bean.dataModelList}" var="linha">
<f:facet name="header">
<rich:columnGroup>
<c:forEach var="coluna" items="#{bean.listaColunas}">
<h:outputText value="#{coluna.label}"/>
</c:forEach>
</rich:columnGroup>
</f:facet>
<!-- Coloque aqui seus valores baseado no objeto linha -->
</rich:dataTable>
Porém, o problema vai aparecer quando vcs forem colocar o valor do objeto, baseado em cada atributo dele.
Fiz uma implementação igual a de cima, porém no componente rich:columnGroup eu criei um binding e fiz ele no java, ficando bem mais facil, mais ou menos assim:
<rich:dataTable value="#{bean.dataModelList}" var="linha">
<f:facet name="header">
<rich:columnGroup binding="#{bean.colunasLabel}">
</f:facet>
<rich:columnGroup binding="#{bean.colunasValor}">
</rich:dataTable>
Assim, a tabela ficou totalmente dinâmica.
Recomendo a segunda opção.
Qualquer dúvida postem aí.
Abraços,