How to pack data into .blend with bpy.data.libraries.write
Edit:

Actually the assumption on what data gets saved was wrong 

data_blocks = set(bpy.context.selected_objects)


is enough to get all the linked materials, nodes etc.

The script to pack the texture images works just by 

import bpy
bpy.ops.file.pack_all() #Tells blender to pack images into the file on save
data_blocks = {*bpy.context.selected_objects, }
bpy.data.libraries.write("my blendfile dir", data_blocks, compress=True)
bpy.ops.file.unpack_all() #Tells blender not to pack images into the file on save


The option compress=True adds compression to the library file.

The Problem

I think the selected_objects data only includes the data of the linked object:


If it is a lamp it will contain brightness type etc 
If it is a mesh it will contain the vertices, faces and the link/name to the materials assignes but NOT the material/nodegroups/textures itself.


Also the Images need to be packed

The Research

Taking a look at the api docs:

https://docs.blender.org/api/blender_python_api_2_77_1/bpy.types.BlendDataLibraries.html


import bpy

filepath = "//new_library.blend"

# write selected objects and their data to a blend file
data_blocks = set(bpy.context.selected_objects)
bpy.data.libraries.write(filepath, data_blocks)


# write all meshes starting with a capital letter and
# set them with fake-user enabled so they aren't lost on re-saving
data_blocks = {mesh for mesh in bpy.data.meshes if mesh.name[:1].isupper()}
bpy.data.libraries.write(filepath, data_blocks, fake_user=True)


# write all materials, textures and node groups to a library
data_blocks = {*bpy.data.materials, *bpy.data.textures, *bpy.data.node_groups}
bpy.data.libraries.write(filepath, data_blocks, compress=True)



The Solution?

import bpy
bpy.ops.file.pack_all() #Pack all images into the file
data_blocks = {*bpy.context.selected_objects, 
*bpy.data.images, 
*bpy.data.materials, 
*bpy.data.textures, 
*bpy.data.node_groups }
bpy.data.libraries.write("my blendfile dir", data_blocks, compress=True)
bpy.ops.file.unpack_all() #Will unpack ALL files in the current file. 


If the pack_all() command does not  work or you don't want it, I think you could loop over all the images and pack them individually:

for image in bpy.data.images:
    image.pack()


I tested the code on packing images (as images) and for me at least it works