The trick consists in using the NOCOPY keyword to pass variables by reference and not by copy.
PROCEDURE PROC(x_out_param OUT NOCOPY VARCHAR2) IS
BEGIN
...
x_out_param := 'some value';
RAISE MY_ERROR_EXCEPTION;
END PROC;
PROCEDURE MAIN(x_out_param OUT VARCHAR2) IS
BEGIN
...
PROC(x_out_param);
EXCEPTION
WHEN MY_ERROR_EXCEPTION THEN RETURN 1;
WHEN OTHERS THEN RETURN 2;
END MAIN;