Los puntos y comas al final de cada cadena están de más, solo generarán un espacio vacío al final de cada array, además, te falta separar a las opciones de las comas que las separan.
    
Código PHP:
Ver original- $str1 = 'color;;;talla;;;peso'; 
- $str2 = 'rojo,azul,verde;;;s,m,l,xl;;;100'; 
-   
- $categorias = explode(';;;', $str1); //Categorías 
- $totalCat = count($categorias); //Total de categorías 
- $opciones = explode(';;;', $str2); //Opciones 
-   
- for ($i = 0; $i < $totalCat; $i++){ 
-     $opc = explode(',', $opciones[$i]); //Sub-grupo de opciones 
-     $tot = count($opc); //Total de opciones del sub-grupo actual 
-     echo '<select>'; 
-     for ($j = 0; $j < $tot; $j++){ 
-         echo '<option>' . $opc[$j] . '</option>'; 
-     } 
-     echo '</select>'; 
- } 
De esta forma, tomo a las categorías y a las opciones, luego, recorro al array de la categorías para ir formando las listas y, en cada iteración, tomo al conjunto de opciones equivalentes, calculo el total que estas suman y las imprimo como opciones de cada lista. 
Así es como quedaría:    
Ahora, solo te queda asignarle valores a las opciones e identificadores a las listas para diferenciarlas unas de otras. 
Saludos