Partiamo dal concetto matematico: la trasposta è la matrice risultante in cui vengono scambiate le righe con le colonne rispetto alla originale.
Quindi se hai una matrice
{
    {1, 2, 3, 4, 5},
    {6, 7, 8, 9, 10}
}
La trasposta ti deve venire:
{
    {1, 6},
    {2, 7},
    {3, 8},
    {4, 9},
    {5, 10}
}
Quindi ti direi innanzitutto di impostare la classe Matrice in questo modo:
public class Matrice {
    private int[][] matrice;
    // costruttore, ecc..
    public Matrice trasposta() {
        // ... completa tu
    }
}
Ovvero nota il metodo trasposta(). Restituisce un NUOVO oggetto Matrice che contiene l'array bidimensionale "trasposto" rispetto all'oggetto Matrice originale. E non ti servono gli ArrayList. Ti basta creare un nuovo array int[][] .
Il design che ti ho indicato è corretto/sensato, perché si ragiona sempre in termini di oggetti Matrice (la tua classe). Tanto per dirne una: non ti devi "inventare" un ulteriore modo per stampare il ArrayList di ArrayList.
Riguardo il codice che hai scritto nella Main, non l'ho letto tutto tutto. Ti consiglio, se ti è possibile di separare bene la lettura/parsing da tutto il resto. Quei split e replaceAll sarebbero evitabili ragionando diversamente (lo split(",") per i valori è l'unico che è davvero utile/sensato).