java – É correto programarmos retornando exceções ao acontecer algo esperado?

Exceções servem para sinalizar que alguma coisa falhou. Exceções verificadas (Exception e suas subclasses que não são RuntimeException) servem para sinalizar coisas que devem ser devidamente tratadas.

Você tem então um método para fazer uma determinada coisa, que é sacar dinheiro de uma conta. Esse método pode falhar? Pode sim! Como ele pode falhar? Se não houver saldo suficiente na conta. Esse caso tem que ser tratado? Com certeza! Logo, isso daí é o caso de criar-se uma exceção verificada.

Ou seja, o que você fez está mais ou menos no caminho certo, mas ainda tem alguns erros. O primeiro é que você tem que fazer isso:

public class SaldoInsuficienteException extends Exception {

    public SaldoInsuficienteException(String msg) {
        super(msg);
    }

}

Ou seja, herde de Exception, não de RuntimeException.

Depois, capturar Exception de forma genérica é uma má prática de programação. A boa prática é capturar e tratar exceções específicas, e não exceções genéricas:

public static void main(String() args) {
    Conta conta = new ContaCorrente();
    conta.deposita(200);
        
    try {
        conta.saca(300);
    } catch (SaldoInsuficienteException e) {
        System.out.println(e.getMessage());
    }
}

Além disso, uma vez que exceções verificadas devem ser tratadas, logo elas devem ser declaradas na cláusula throws:

class ContaCorrente extends Conta {

    public void deposita(double valor) {
        super.saldo += (valor);
    }

    public void saca(double valor) throws SaldoInfuficienteException {
        if (super.saldo < valor) {
            throw new SaldoInsuficienteException(
                    "O saldo não é suficiente para saque, Saldo atual é: "
                    + super.saldo + " Você tentou sacar " + valor);
        }
        super.saldo += (valor - 0.10);
    }

}