How can I reduce the redundancy of this code, so one function can perform the task of printing on Serial and Softserial?
Just send your data to a tee: this is a type of pipe fitting where you
push the data through one end and it goes out through the other two
ends. As it happens, both Serial and Softserial (and almost anything
that can print()) inherit from the virtual Print class. You can
implement a tee as a Print that outputs to two Prints:



class Tee : public Print
{
public:
    Tee(Print &amp;_p1, Print &amp;_p2)
    : p1(_p1), p2(_p2)
    {}

    size_t write(uint8_t c)
    {
        size_t count1 = p1.write(c);
        size_t count2 = p2.write(c);
        return min(count1, count2);
    }
private:
    Print &amp;p1, &amp;p2;
};


The write(uint8_t) is the only method you really need to implement to
have a working Print. Then, all the print() and println() methods
will work.

Example usage:

Tee dualSerial(Serial, mySerial);
dualSerial.print("The answer is ");
dualSerial.println(42);


Note that parseInt() will not work, as it is not a method from
Print. But if you think twice, you will realize that parseInt() on a
pair of channels just does not make sense.