Il dubbio principale e' se nelle classi derivate da Observer tengo come riferimento un dato membro di tipo Subject o DerSubject, cioe' quello che sara' il reale tipo di subject osservato: credo la seconda, anche se nell'esempio di codice sopra postato ho fatto il contrario.
No, è la prima. Passando un puntatore a classe base perdi le informazioni su cosa sia la classe derivata, cosa che un puntatore a DerSubject richiede. Ricorda che un observer può osservare diversi subject (ragione per cui si passa un puntatore a subject in update() ), come un subject può avere diversi observer e non è possibile (in teoria) tenere traccia di tutte le possibili implementazioni.

Inoltre, potrebbe mai essere necessario implementare un metodo setSubject nelle classi derivate da Observer per poter cambiare il Subject osservato?

Lo vedo poco utile. Ogni volta che devi osservare un subject diverso devi andare di setSubject.
Personalmente aggiungerei due metodi virtuali addSubject(Subject*) / removeSubject(Subject*) che mi consentano l'inserimento in un std::set<> delle varie istanze subject che voglio controllare in update().
In codice:
codice:
class Subject;

class Observer
{
  public:
    virtual ~Observer(){};
    virtual void update(Subject*subject)=0;
    virtual void addSubject(Subject* sub)=0;
    virtual void removeSubject(Subject* sub)=0;
  protected:
    Observer(){};
};

class Subject
{
  public:
    virtual ~Subject(){};
    virtual void attach(Observer*observer);
    virtual void detach(Observer*observer);
    virtual void notify();
  protected:
    Subject(){};
  private:
    std::set<Observer*>mObserverList;
};


class DerSubject: public Subject {};

class ObserverTester: public Observer
{
  public:
    ObserverTester(Subject* subject)
    {
            addSubject(subject);
    }; 
    
    void addSubject(Subject* sub) {
      sub=subject;
      sub->attach(this);
        mSubjects.insert(sub);
    }

    void removeSubject(Subject* sub) {
      sub->dettach(this); 
        mSubjects.remove(sub);
    }
    
    
    void update(Subject* subject) override
    {
      
      auto sub = mSubject.find(subject);
      if(sub != mSubjects.end())
      {
        std::cout<<"\nHello from observer "<<this;
        std::cout<<"\nI'm observing subject "<<sub;
      }
    };
  private:
    std::set<Subject*> mSubjects;
};