Puedes usar
is_dir dentro del ciclo, para saber si lo que estas leyendo es un directorio, y si es asi abrirlo con opedir y hacer el mismo proceso de leer su contenido.
Si solo son dos niveles (categoria y subcategoria) puedes poner todo el proceso de nuevo dentro del segundo ciclo, o usar una funcion. Si puede que sean mas niveles y/o no siempre seran la misma cantidad podrias usar una funcion recursiva.