Is this an excessive abstraction using objects?
I think the use of classes here is excessive because of complexity added by their structure and inheritance. Since your objects have only one method putObject you can make abstraction on the function level. So you can just use closures to save state by returning a function that will put objects. In this case s3Cache will use only one function of s3Legacy as a dependency.
Here is the code:
const s3Legacy = (sdk, bucket) =&gt; function putObject(key, body, callback) {
    sdk.putObject({ Bucket: bucket, Key: key, Body: body }, callback);
}

const s3Cache = (putObjectLegacy) =&gt; function putObject(params, callback) {
    const toS3Key = (unitId, incidentTimestamp, incidentId, archiveIncidentObjectName) =&gt; 'implementation';
    const toTimestampObject = (timestamp) =&gt; 'implementation';

    const key = toS3Key(
        params.unitId,
        toTimestampObject(params.timestamp),
        params.eventId,
        params.eventFileName
    );

    putObjectLegacy(key, params.body, callback);
}

module.exports.handle = (event, context, cb) =&gt; {
    const s3Sdk = new AWS.S3({ region: config.s3.region });
    const putObjectLegacy = s3Legacy(s3Sdk, config.s3.legacyBucketName);
    const putObjectCache = s3Cache(s3Legacy(s3Sdk, config.s3.cacheBucketName));

    putObjectLegacy(key, event.body, callback);
    putObjectCache({
        unitId: event.pathParameters.unitId,
        timestamp: event.timestamp,
        eventId: event.id,
        eventFileName: event.id,
        body: event.body
    }, callback);
}