In BEFORE UPDATE TRIGGER, how do I prevent changing nothing but timestamp?
Make a copy of old, update the timestamp and compare it with new.

CREATE OR REPLACE FUNCTION verify() RETURNS TRIGGER AS $verify$
    DECLARE
        rec record;
    BEGIN
        IF (TG_OP = 'UPDATE') THEN
            rec=old;
            rec.timestamp = NEW.timestamp;
            IF rec IS DISTINCT FROM NEW THEN
                    RETURN NEW;
            ELSE
                    RAISE WARNING 'Must change something besides timestamp.';
                    RETURN NULL;
            END IF;
        END IF;
        RETURN NEW;
    END;
$verify$ LANGUAGE plpgsql;


(edit: thanks @ Granny Aching)

If you don't need OLD later in the trigger you can modify it without harm.

CREATE OR REPLACE FUNCTION verify() RETURNS TRIGGER AS $verify$
    BEGIN
        IF (TG_OP = 'UPDATE') THEN
            OLD.timestamp = NEW.timestamp;
            IF  OLD IS DISTINCT FROM NEW THEN
                    RETURN NEW;
            ELSE
                    RAISE WARNING 'Must change something besides timestamp.';
                    RETURN NULL;
            END IF;
        END IF;
        RETURN NEW;
    END;
$verify$ LANGUAGE plpgsql;