Você quer algo assim:
select t.table_name, level,lpad(' ', 2 * (level - 1))||t.table_name
from user_tables t
join user_constraints c1
on (t.table_name = c1.table_name
and c1.constraint_type in ('U', 'P'))
left join user_constraints c2
on (t.table_name = c2.table_name
and c2.constraint_type='R')
start with t.table_name = 'ROOT_TAB'
connect by prior c1.constraint_name = c2.r_constraint_name
O problema com a consulta original é que uc.constraint_name para a tabela filha é o nome da chave estrangeira. Isso é bom para conectar o primeiro filho à tabela raiz, mas não é o que você precisa para conectar os filhos do segundo nível ao primeiro. É por isso que você precisa unir as restrições duas vezes -- uma vez para obter a chave primária da tabela, uma vez para obter as chaves estrangeiras.
Como um aparte, se você estiver consultando as visualizações all_* em vez das visualizações user_*, geralmente deseja juntá-las em table_name AND owner, não apenas table_name. Se vários esquemas tiverem tabelas com o mesmo nome, juntar apenas table_name dará resultados incorretos.